#ifndef NETLIB_TCPCONNECTION_H
#define NETLIB_TCPCONNECTION_H

// TCP连接管理类

#include "noncopyable.h"
#include "StringPiece.h"
#include "Types.h"
#include "Callbacks.h"
#include "Buffer.h"
#include "InetAddress.h"

#include <memory>
#include <boost/any.hpp>

struct tcp_info;

namespace netlib
{

namespace net
{

class Channel;
class EventLoop;
class Socket;

class TcpConnection : noncopyable, // TCP连接管理类，不可拷贝，生命周期由智能指针管理
                    // 保证智能指针的引用加一，而不是构建一个新的智能指针对象
                    public std::enable_shared_from_this<TcpConnection>
{
public:
    TcpConnection(EventLoop* loop,
                    const string& name,
                    int sockfd,
                    const InetAddress& localAddr,
                    const InetAddress& peerAddr);

    ~TcpConnection();

    EventLoop* getLoop() const { return loop_; } // 返回所属的EventLoop对象

    const string& name() const { return name_; } // 返回连接名称

    const InetAddress& localAddress() const { return localAddr_; } // 返回本地的协议地址

    const InetAddress& peerAddress() const { return peerAddr_; } // 返回对端的协议地址

    bool connected() const { return state_ == kConnected; } // 查询连接是否已成功建立

    bool disconnected() const { return state_ == kDisconnected; } // 查询连接是否销毁

    bool getTcpInfo(struct tcp_info*) const; // 获取TCP相关信息

    string getTcpInfoString() const; // 获取TCP相关信息并将其转化成字符串

    void send(const void* message, int len); // 发送数据，传入void*和len

    void send(const StringPiece& message); // 发送数据，传入StringPiece&

    void send(Buffer* message); // 发送数据，传入Buffer*

    void shutdown(); // 关闭连接，shutdownInLoop的封装

    void forceClose(); // 超时关闭连接，forceCloseInLoop的封装

    void forceCloseWithDelay(double seconds); // 创建一个定时器，超时关闭连接

    // 禁用Nagle算法，可以避免连续发包出现延迟，对于低延迟服务很重要
    void setTcpNoDelay(bool on);
    
    void startRead(); // 注册连接的监听可读事件，startReadInLoop的封装

    void stopRead(); // 撤销连接的监听可读事件，stopReadInLoop的封装

    bool isReading() const { return reading_; }; // 查询是否监听可读事件

    // 设置用户的自定义对象
    void setContext(const boost::any& context) { context_ = context; }

    // 返回const类型的用户自定义对象
    const boost::any& getContext() const { return context_; }

    // 返回用户自定义对象
    boost::any* getMutableContext() { return &context_; }

    // 设置新连接到来的回调函数
    void setConnectionCallback(const ConnectionCallback& cb)
    { connectionCallback_ = cb; }

    // 设置消息到来的回调函数
    void setMessageCallback(const MessageCallback& cb)
    { messageCallback_ = cb; }

    // 设置低水位标回调函数
    void setWriteCompleteCallback(const WriteCompleteCallback& cb)
    { writeCompleteCallback_ = cb; }

    // 设置高水位标回调函数，highWaterMark高水位标
    void setHighWaterMarkCallback(const HighWaterMarkCallback& cb, size_t highWaterMark)
    { highWaterMarkCallback_ = cb; highWaterMark_ = highWaterMark; }

    Buffer* inputBuffer() // 返回输入缓冲区对象
    { return &inputBuffer_; }

    Buffer* outputBuffer() // 返回输出缓冲区对象
    { return &outputBuffer_; }

    void setCloseCallback(const CloseCallback& cb) // 设置关闭连接的回调函数
    { closeCallback_ = cb; }

    void connectEstablished(); // 将连接插入到事件表中进行关注

    void connectDestroyed(); // 销毁连接

private:
    // 枚举连接状态，已销毁、建立中、已建立、销毁中
    enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };

    void handleRead(Timestamp receiveTime); // 可读事件处理函数

    void handleWrite(); // 可写事件处理函数

    void handleClose(); // 关闭事件回调函数

    void handleError(); // 错误事件回调函数

    void sendInLoop(const StringPiece& message);

    void sendInLoop(const void* message, size_t len);

    void shutdownInLoop(); // 优雅的关闭连接

    void forceCloseInLoop(); // 超时关闭连接

    void setState(StateE s) { state_ = s; } // 设置连接状态

    const char* stateToString() const; // 将连接状态转成字符串返回

    void startReadInLoop(); // 注册事件表的可读事件

    void stopReadInLoop(); // 撤销连接事件表中可读事件

    EventLoop* loop_;       // 所属的EventLoop对象
    const string name_;     // 连接名称
    StateE state_;          // 连接状态
    bool reading_;          // 是否监听可读事件
    std::unique_ptr<Socket> socket_;        // 持有的描述符fd，智能指针管理
    std::unique_ptr<Channel> channel_;      // 持有的通道对象，智能指针管理
    const InetAddress localAddr_;           // 本地的协议地址
    const InetAddress peerAddr_;            // 对端的协议地址
    ConnectionCallback connectionCallback_;         // 连接到来的回调函数
    MessageCallback messageCallback_;               // 消息到来的回调函数
    WriteCompleteCallback writeCompleteCallback_;   // 数据发送完毕回调函数，数据到内核
                                                    // 低水位标，outputBuffer_清空时调用
    HighWaterMarkCallback highWaterMarkCallback_;   // 高水位标回调函数
    CloseCallback closeCallback_;       // 关闭连接的回调函数
    size_t highWaterMark_;              // 高水位标
    Buffer inputBuffer_;                // 接受缓冲区
    Buffer outputBuffer_;               // 发送缓冲区

    boost::any context_;                // 绑定一个未知类型的上下文对象
                                        // 用户可以为每一个对象绑定一个自定义对象

}; // class TcpConnection end

typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;

} // namespace net end

} // namespace netlib end

#endif